﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;

namespace Modbus_Tool
{
    public partial class ModbusTool : Form
    {
        int equ_num = 1;

        int re_data_num;

        UInt32 timer_tick;
        UInt64 timer_cache;
        

        int device_max_num = 21;//从机模式


        byte[] myarray = new byte[500];

        string xmlPath = System.Environment.CurrentDirectory + "\\data.xml";
        Timer time1 = new Timer();
        public ModbusTool()
        {
            InitializeComponent();
        }

        private void ModbusTool_Load(object sender, EventArgs e)
        {
            if (File.Exists(xmlPath))
            {
                //将XML文件加载进来
                XDocument document = XDocument.Load(xmlPath);
                //获取到XML的根元素进行操作
                XElement root = document.Root;

                /*参数*/
                XElement para = root.Element("para");

                /*获取类型的值*/
                XElement type = para.Element("type");
                type_comboBox.Text = type.Value;

                /*获取模式的值*/
                XElement mode = para.Element("mode");
                mode_comboBox.Text = mode.Value;

            }
            else
            {

                //创建一个XML文档对象
                XmlDocument doc = new XmlDocument();
                //声明XML头部信息
                XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
                //添加进doc对象子节点
                doc.AppendChild(dec);
                //创建根节点
                XmlElement root = doc.CreateElement("data_chache");
                doc.AppendChild(root);

                //再创建根节点下的子节点
                XmlElement para = doc.CreateElement("para");
                //设置子节点属性
                para.SetAttribute("paranum", "1");


                //子节点下再创建标记
                XmlElement typeName = doc.CreateElement("type");
                //<type>的内容
                XmlText xmlText = doc.CreateTextNode("从机");
                //将内容添加到<type>标记
                typeName.AppendChild(xmlText);
                //再将<type>标记添加到<para>标记的子节点下
                para.AppendChild(typeName);


                //子节点下再创建标记
                XmlElement modeName = doc.CreateElement("mode");
                //<mode>的内容
                XmlText modeText = doc.CreateTextNode("RTU");
                //将内容添加到<type>标记
                modeName.AppendChild(modeText);
                //再将<type>标记添加到<para>标记的子节点下
                para.AppendChild(modeName);

                //子节点下再创建标记
                XmlElement host_para_num = doc.CreateElement("host_para_num");
                XmlText host_para_numText = doc.CreateTextNode("0");
                host_para_num.AppendChild(host_para_numText);
                para.AppendChild(host_para_num);


                //最后把标记添加到根节点<para>子节点下
                root.AppendChild(para);

                //doc文档对象保存写入
                doc.Save("data.xml");

                type_comboBox.Text = "从机";
                mode_comboBox.Text = "RTU";
            }
            selet_baudrate_comboBox.Text = "9600";//波特率默认 

            this.time1.Interval = 10;
            this.time1.Tick += new System.EventHandler(this.timer_Tick);
            this.time1.Start();

        }



        private void equ_add_button_Click(object sender, EventArgs e)
        {
            int flag = 0;
            if (equ_num < device_max_num)
            {
                equ_treeView.Nodes.Add("设备" + equ_num.ToString());
                XmlDocument doc = new XmlDocument();
                //加载根目录下XML文件
                doc.Load(xmlPath);
                //获取根节点
                XmlElement root = doc.DocumentElement;
                //获取<设备>子节点 
                XmlNodeList personNodes = root.GetElementsByTagName("Device");
                //使用foreach循环读出集合
                foreach (XmlNode node in personNodes)
                {
                    string id = ((XmlElement)node).GetAttribute("D_id");
                    if (id == equ_num.ToString())
                    {
                        flag = 1;
                        break;
                    }

                }
                if (flag == 1)
                {

                }
                else
                {
                    //创建根节点下的子节点
                    XmlElement Device = doc.CreateElement("Device");
                    Device.SetAttribute("D_id", equ_num.ToString());
                    ID_textBox.Text = equ_num.ToString();


                    //添加设备参数个数
                    XmlElement Device_parameter_num = doc.CreateElement("parameter_num");
                    XmlText Device_parameter_num_Text = doc.CreateTextNode("0");
                    Device_parameter_num.AppendChild(Device_parameter_num_Text);


                    //将上面创建的标记添加到<Device>标记
                    Device.AppendChild(Device_parameter_num);
                    //将上面创建的标记添加到<data_chache>根标记
                    root.AppendChild(Device);
                    //最后一步不要忘记了保存
                    doc.Save(xmlPath);
                }
                equ_num++;
            }
            else
            {

               MessageBox.Show("从机模式，最多添加20个设备！");
            }
        }

        private void equ_dele_button_Click(object sender, EventArgs e)
        {
            if (equ_treeView.SelectedNode == null)
            {
                MessageBox.Show("请选择要删除的设备！");
                return;
            }
            string str1 = equ_treeView.SelectedNode.Text.Substring(2);
            equ_treeView.SelectedNode.Remove();
            XmlDocument doc = new XmlDocument();
            doc.Load(xmlPath);
            XmlElement root = doc.DocumentElement;
            //筛选出符合条件的标记
            XmlElement selectEle = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id='"+ str1 + "']");
            //删除指定子元素
            root.RemoveChild(selectEle);
            //还是那句话不要忘记保存
            doc.Save(xmlPath);
            equ_num--;
        }

        private void para_add_button_Click(object sender, EventArgs e)
        {
            int parameter_flag = 0;

            if (type_comboBox.Text == "主机")
            {
                XmlDocument doc = new XmlDocument();
                //加载根目录下XML文件
                doc.Load(xmlPath);
                //获取根节点
                XmlElement root = doc.DocumentElement;

                //添加设备IP标记
                XmlElement Device = (XmlElement)root.SelectSingleNode("/data_chache/para[@paranum='1']");

                //获取该标记下的子元素
                XmlElement host_para_num = (XmlElement)Device.GetElementsByTagName("host_para_num")[0];

                int num = Convert.ToInt32(host_para_num.InnerText);
                num++;
                if (num > 11)
                {
                    MessageBox.Show("最多添加10个参数！");
                    return;
                }
                host_para_num.InnerText = num.ToString();


                //获取<parameter>子节点 
                XmlNodeList parameterNodes = Device.GetElementsByTagName("host_para");
                //使用foreach循环读出集合
                foreach (XmlNode node in parameterNodes)
                {
                    string id = ((XmlElement)node).GetAttribute("host_para_ID");
                    if (id == num.ToString())
                    {
                        parameter_flag = 1;
                        break;
                    }
                }
                if (parameter_flag == 1)
                {

                }
                else
                {
                    para_treeView.Nodes.Add("参数" + num.ToString());
                    //再创建根节点下的子节点
                    XmlElement host_para = doc.CreateElement("host_para");
                    host_para.SetAttribute("host_para_ID", num.ToString());


                    XmlElement host_reg_addr = doc.CreateElement("host_reg_addr");
                    XmlText reg_addr = doc.CreateTextNode("0");
                    host_reg_addr.AppendChild(reg_addr);

                    XmlElement host_reg_mode = doc.CreateElement("host_reg_mode");
                    XmlText reg_mode = doc.CreateTextNode("整型");
                    host_reg_mode.AppendChild(reg_mode);

                    XmlElement host_reg_num = doc.CreateElement("host_reg_num");
                    XmlText reg_num = doc.CreateTextNode("0");
                    host_reg_num.AppendChild(reg_num);


                    XmlElement host_reg_value = doc.CreateElement("host_reg_value");
                    XmlText reg_value = doc.CreateTextNode("0");
                    host_reg_value.AppendChild(reg_value);


                    //再标记的子节点下
                    host_para.AppendChild(host_reg_addr);
                    host_para.AppendChild(host_reg_mode);
                    host_para.AppendChild(host_reg_num);
                    host_para.AppendChild(host_reg_value);

                    //Device标记添加到<data_chache>根标记
                    root.AppendChild(host_para);
                    //最后一步不要忘记了保存
                    doc.Save(xmlPath);
                }
            }
            else
            {
                XmlDocument doc = new XmlDocument();
                //加载根目录下XML文件
                doc.Load(xmlPath);
                //获取根节点
                XmlElement root = doc.DocumentElement;

                //添加设备IP标记
                XmlElement Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id='" + ID_textBox.Text + "']");

                //获取该标记下的子元素
                XmlElement Device_parameter_num = (XmlElement)Device.GetElementsByTagName("parameter_num")[0];

                int num = Convert.ToInt32(Device_parameter_num.InnerText);
                num++;
                if (num > 11)
                {
                    MessageBox.Show("最多添加10个参数！");
                    return;
                }
                Device_parameter_num.InnerText = num.ToString();


                //获取<parameter>子节点 
                XmlNodeList parameterNodes = Device.GetElementsByTagName("parameter");
                //使用foreach循环读出集合
                foreach (XmlNode node in parameterNodes)
                {
                    string id = ((XmlElement)node).GetAttribute("P_id");
                    if (id == num.ToString())
                    {
                        parameter_flag = 1;
                        break;
                    }
                }
                if (parameter_flag == 1)
                {

                }
                else
                {
                    para_treeView.Nodes.Add("参数" + num.ToString());
                    //新建新节点参数
                    XmlElement Device_parameter = doc.CreateElement("parameter");
                    //参数的设备ID
                    Device_parameter.SetAttribute("D" + ID_textBox.Text + "_P_id", num.ToString());

                    //新建新节点参数的属性
                    XmlElement Device_parameter_address = doc.CreateElement("address");
                    //新建节点参数的文本
                    XmlText parameter_address = doc.CreateTextNode("4001");

                    //将内容添加到<Device_parameter_para_mode>标记
                    Device_parameter_address.AppendChild(parameter_address);

                    XmlElement Device_parameter_para_mode = doc.CreateElement("para_mode");
                    XmlText parameter_para_mode = doc.CreateTextNode("整型");
                    Device_parameter_para_mode.AppendChild(parameter_para_mode);

                    XmlElement Device_parameter_reg_num = doc.CreateElement("reg_num");
                    XmlText parameter_reg_num = doc.CreateTextNode("1");
                    Device_parameter_reg_num.AppendChild(parameter_reg_num);

                    XmlElement Device_parameter_reg_value = doc.CreateElement("reg_value");
                    XmlText parameter_reg_value = doc.CreateTextNode("1");
                    Device_parameter_reg_value.AppendChild(parameter_reg_value);


                    //Device_parameter_para_mode标记添加到<Device_parameter>标记
                    Device_parameter.AppendChild(Device_parameter_address);
                    Device_parameter.AppendChild(Device_parameter_para_mode);
                    Device_parameter.AppendChild(Device_parameter_reg_num);
                    Device_parameter.AppendChild(Device_parameter_reg_value);
                    //Device_parameter标记添加到<Device>标记
                    Device.AppendChild(Device_parameter);
                    //Device标记添加到<data_chache>根标记
                    root.AppendChild(Device);
                    //最后一步不要忘记了保存
                    doc.Save(xmlPath);
                }
            }
        }

        private void para_dele_button_Click(object sender, EventArgs e)
        {
            if (para_treeView.SelectedNode == null)
            {
                MessageBox.Show("请选择要删除的参数！");
                return;
            }

            para_treeView.SelectedNode.Remove();

            XmlDocument doc = new XmlDocument();
            //加载根目录下XML文件
            doc.Load(xmlPath);
            //获取根节点
            XmlElement root = doc.DocumentElement;

            string str = ID_textBox.Text;
            string str1 = para_ID_textBox.Text;
            String str2 = "D" + ID_textBox.Text + "_P_id";

            if (type_comboBox.Text == "主机")
            {
                XmlElement select_Device = (XmlElement)root.SelectSingleNode("/data_chache/para[@paranum = '1']");

                XmlElement Device_parameter_num1 = (XmlElement)select_Device.GetElementsByTagName("host_para_num")[0];
                int num = Convert.ToInt32(Device_parameter_num1.InnerText);
                num--;
                Device_parameter_num1.InnerText = num.ToString();
                int ID = Convert.ToInt32(para_ID_textBox.Text);
                XmlElement selectEle1 = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID = '" +str1 + "']");
                root.RemoveChild(selectEle1);
                doc.Save(xmlPath);
            }
            else
            {
                XmlElement select_Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id = '" + str + "']");

                XmlElement Device_parameter_num1 = (XmlElement)select_Device.GetElementsByTagName("parameter_num")[0];
                int num = Convert.ToInt32(Device_parameter_num1.InnerText);
                num--;
                Device_parameter_num1.InnerText = num.ToString();



                XmlElement selectEle1 = (XmlElement)select_Device.SelectSingleNode("/data_chache/Device/parameter[@" + str2 + " = '" + str1 + "']");
                select_Device.RemoveChild(selectEle1);
                doc.Save(xmlPath);
            }
        }

        public static int crc16(byte[] data, int size)
        {
            int crc = 0xFFFF;
            byte data_t;
            int i = 0;
            int j = 0;
            if (data == null)
            {
                return 0;
            }
            for (j = 0; j < size; j++)
            {
                data_t = data[j];
                crc = (data_t ^ (crc));
                for (i = 0; i < 8; i++)
                {
                    if ((crc & 0x1) == 1)
                    {
                        crc = (crc >> 1) ^ 0xA001;
                    }
                    else
                    {
                        crc >>= 1;
                    }
                }
            }
            return crc;
        }

        private void host_sent_data()
        {
            byte[] data_send = new byte[500];
            int data_send_num = 0;
            int data_send_num_cache;
            int mycrc = 0;
            int host_reg_addr_value;
            int host_reg_value;

            int num_cache;
            
            
            data_send_num = 0;
            XmlDocument doc = new XmlDocument();
            //加载根目录下XML文件
            doc.Load(xmlPath);
            //获取根节点
            XmlElement root = doc.DocumentElement;

            //添加设备IP标记
            XmlElement Device = (XmlElement)root.SelectSingleNode("/data_chache/para[@paranum='1']");

            //获取该标记下的子元素
            XmlElement host_para_num = (XmlElement)Device.GetElementsByTagName("host_para_num")[0];

            int num = Convert.ToInt32(host_para_num.InnerText);
            byte[] data_cache = BitConverter.GetBytes(Convert.ToInt32(ID_textBox.Text, 16));
            data_send[data_send_num++] = data_cache[0];
            data_send[data_send_num++] = 0X10;

            XmlElement select = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID='1']");
            XmlElement host_reg_addr = (XmlElement)select.GetElementsByTagName("host_reg_addr")[0];
            host_reg_addr_value = Convert.ToInt32(host_reg_addr.InnerText, 16);
            data_cache = BitConverter.GetBytes(host_reg_addr_value);
            data_send[data_send_num++] = data_cache[1];
            data_send[data_send_num++] = data_cache[0];


            data_send_num+=3;

            for (int i = 1; i < num + 1; i++)
            {
                XmlElement select_host_para = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID='" + i.ToString() + "']");
                XmlElement host_reg_addr_now = (XmlElement)select_host_para.GetElementsByTagName("host_reg_addr")[0];
                XmlElement host_para_mode = (XmlElement)select_host_para.GetElementsByTagName("host_reg_mode")[0];
                XmlElement host_reg_value_value = (XmlElement)select_host_para.GetElementsByTagName("host_reg_value")[0];

                if (host_para_mode.InnerText == "浮点型")
                {
                    float x = float.Parse(host_reg_value_value.InnerText);
                    data_cache = BitConverter.GetBytes(x);
                    data_send[data_send_num++] = data_cache[3];
                    data_send[data_send_num++] = data_cache[2];
                    data_send[data_send_num++] = data_cache[1];
                    data_send[data_send_num++] = data_cache[0];
                    num_cache = 1;
                }
                else
                {
                    host_reg_value = Convert.ToInt32(host_reg_value_value.InnerText, 10);
                    data_cache = BitConverter.GetBytes(host_reg_value);
                    data_send[data_send_num++] = data_cache[1];
                    data_send[data_send_num++] = data_cache[0];
                    num_cache = 0;
                }
                

                try
                {
                    XmlElement select_next = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID='" + (i + 1).ToString() + "']");
                    XmlElement host_reg_addr_next = (XmlElement)select_next.GetElementsByTagName("host_reg_addr")[0];

                    if (Convert.ToInt32(host_reg_addr_next.InnerText, 16) < Convert.ToInt32(host_reg_addr_now.InnerText, 16))
                    {
                        break;
                    }
                    else
                    {
                        for (int n = 1; n < (Convert.ToInt32(host_reg_addr_next.InnerText, 16) - Convert.ToInt32(host_reg_addr_now.InnerText, 16)-num_cache); n++)
                        {
                            data_send[data_send_num++] = 0X00;
                            data_send[data_send_num++] = 0X00;
                        }
                    }
                }
                catch
                {
                }
            }
            doc.Save(xmlPath);
            data_send_num_cache = data_send_num - 7;
            data_cache = BitConverter.GetBytes(data_send_num_cache);
            data_send[6] = data_cache[0];
            data_cache = BitConverter.GetBytes(data_send_num_cache/2);
            data_send[4] = 0;
            data_send[5] = data_cache[0];

            mycrc = crc16(data_send, data_send_num);
            data_cache = BitConverter.GetBytes(mycrc & 0xff);
            data_send[data_send_num++] = data_cache[0];
            data_cache = BitConverter.GetBytes((mycrc >> 8) & 0xff);
            data_send[data_send_num++] = data_cache[0];

            if (open_com_button.Enabled == false)
            {
                serialPort.Write(data_send, 0, data_send_num);
            }
            timer_cache = timer_tick;


        }


        private void analysis_data()
        {

            int current_para_num;
            byte[] data_send = new byte[500];
            int data_send_num = 0;
            int mycrc = 0;

            int num_cache;

            data_send[data_send_num++] = myarray[0];
            data_send[data_send_num++] = 0X03;
            byte[] data_cache = BitConverter.GetBytes(myarray[5] * 2);
            data_send[data_send_num++] = data_cache[0];

            XmlDocument doc = new XmlDocument();
            //加载根目录下XML文件
            doc.Load(xmlPath);
            //获取根节点
            XmlElement root = doc.DocumentElement;

            string str = myarray[0].ToString();
            String str2 = "D" + str + "_P_id";

            XmlElement select_Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id = '" + str + "']");


            XmlElement selet_Device_parameter_num = (XmlElement)select_Device.GetElementsByTagName("parameter_num")[0];

            current_para_num = Convert.ToInt32(selet_Device_parameter_num.InnerText, 10) + 1;

            for (int i = 1; i < current_para_num; i++)
            {
                XmlElement selectEle = (XmlElement)select_Device.SelectSingleNode("/data_chache/Device/parameter[@" + str2 + " = '" + i.ToString() + "']");
                XmlElement address = (XmlElement)selectEle.GetElementsByTagName("address")[0];
                XmlElement para_mode = (XmlElement)selectEle.GetElementsByTagName("para_mode")[0];
                XmlElement reg_num = (XmlElement)selectEle.GetElementsByTagName("reg_num")[0];
                XmlElement reg_value = (XmlElement)selectEle.GetElementsByTagName("reg_value")[0];


                if (reg_value.InnerText == "浮点型")
                {
                    float x = float.Parse(reg_value.InnerText);
                    data_cache = BitConverter.GetBytes(x);
                    data_send[data_send_num++] = data_cache[3];
                    data_send[data_send_num++] = data_cache[2];
                    data_send[data_send_num++] = data_cache[1];
                    data_send[data_send_num++] = data_cache[0];
                    num_cache = 1;
                }
                else
                {
                    data_cache = BitConverter.GetBytes(Convert.ToInt32(reg_value.InnerText, 10));
                    data_send[data_send_num++] = data_cache[1];
                    data_send[data_send_num++] = data_cache[0];
                    num_cache = 0;
                }

                if (data_send_num > (data_send[2]))
                {
                    break;
                }

                try
                {
                    XmlElement selectEle_next = (XmlElement)select_Device.SelectSingleNode("/data_chache/Device/parameter[@" + str2 + " = '" + (i + 1).ToString() + "']");
                    XmlElement address_next = (XmlElement)selectEle_next.GetElementsByTagName("address")[0];
                    XmlElement reg_num_next = (XmlElement)selectEle_next.GetElementsByTagName("reg_num")[0];

                    if (Convert.ToInt32(address_next.InnerText, 16) < Convert.ToInt32(address.InnerText, 16))
                    {
                        break;
                    }
                    else
                    {
                        for (int num = 0; num < (Convert.ToInt32(address_next.InnerText, 16) - Convert.ToInt32(address.InnerText, 16) - Convert.ToInt32(reg_num.InnerText, 16)-num_cache); num++)
                        {
                            data_send[data_send_num++] = 0X00;
                            data_send[data_send_num++] = 0X00;
                        }
                    }
                }
                catch
                {
                    MessageBox.Show("调试工具设置的参数少于控制卡设置的参数");
                }

            }
            doc.Save(xmlPath);
            mycrc = crc16(data_send, data_send_num);
            data_cache = BitConverter.GetBytes(mycrc & 0xff);
            data_send[data_send_num++] = data_cache[0];
            data_cache = BitConverter.GetBytes((mycrc >> 8) & 0xff);
            data_send[data_send_num++] = data_cache[0];

            if (open_com_button.Enabled == false)
            {
                serialPort.Write(data_send, 0, data_send_num);
            }
        }

        private void uodate_device_para(int num)
        {
            XmlDocument doc = new XmlDocument();
            //加载根目录下XML文件
            doc.Load(xmlPath);
            //获取根节点
            XmlElement root = doc.DocumentElement;

            /*设备*/
            XmlElement selet_Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id='" + num.ToString()+"']");


            //获取该标记下的子元素
            

            ID_textBox.Text = num.ToString();


            XmlElement Device_parameter_num = (XmlElement)selet_Device.GetElementsByTagName("parameter_num")[0];

            if ((Convert.ToInt32(Device_parameter_num.InnerText)) == 0)
            {
                return;
            }
            else
            {
                //获取<parameter>子节点 
                XmlNodeList parameterNodes = selet_Device.GetElementsByTagName("parameter");
                //使用foreach循环读出集合
                foreach (XmlNode node in parameterNodes)
                {
                    string id = ((XmlElement)node).GetAttribute("D" + ID_textBox.Text + "_P_id");//, num.ToString());
                    para_treeView.Nodes.Add("参数" + id);
                }
            }
        }


        private void uodate_para_para(int num)
        {
            para_ID_textBox.Text = num.ToString();

            XmlDocument doc = new XmlDocument();
            //加载根目录下XML文件
            doc.Load(xmlPath);
            //获取根节点
            XmlElement root = doc.DocumentElement;

            string str = ID_textBox.Text;
            string str1 = para_ID_textBox.Text;
            String str2 = "D" + ID_textBox.Text + "_P_id";

            XmlElement select_Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id = '" + str + "']");

            XmlElement selectEle = (XmlElement)select_Device.SelectSingleNode("/data_chache/Device/parameter[@" + str2 + " = '" + str1 + "']");
            /*获取起始地址的值*/
            XmlElement para_address = (XmlElement)selectEle.GetElementsByTagName("address")[0];
            address_textBox.Text = para_address.InnerText;

            /*获取模式的值*/
            XmlElement para_mode1 = (XmlElement)selectEle.GetElementsByTagName("para_mode")[0];
            para_mode_comboBox.Text = para_mode1.InnerText;

            if (para_mode1.InnerText == "浮点型")
            {
                /*获取寄存器个数的值*/
                XmlElement register1 = (XmlElement)selectEle.GetElementsByTagName("reg_num")[0];
                register1.InnerText = "2";
                register_textBox.Text = "2";
                register_textBox.Enabled = false;
            }
            else
            {
                /*获取寄存器个数的值*/
                XmlElement register1 = (XmlElement)selectEle.GetElementsByTagName("reg_num")[0];
                register_textBox.Text = register1.InnerText;
                register_textBox.Enabled = true;
            }
            

            /*获取寄存器个数的值*/
            XmlElement registernum11 = (XmlElement)selectEle.GetElementsByTagName("reg_value")[0];
            register1_text.Text = registernum11.InnerText;

            doc.Save(xmlPath);
        }

        private void address_textBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                XmlDocument doc = new XmlDocument();
                //加载根目录下XML文件
                doc.Load(xmlPath);
                //获取根节点
                XmlElement root = doc.DocumentElement;

                string str = ID_textBox.Text;
                string str1 = para_ID_textBox.Text;
                String str2 = "D" + ID_textBox.Text + "_P_id";

                if (type_comboBox.Text == "主机")
                {
                    XmlElement select = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID = '" + str1 + "']");
                    XmlElement nameEle = (XmlElement)select.GetElementsByTagName("host_reg_addr")[0];
                    nameEle.InnerText = address_textBox.Text;
                }
                else
                {
                    XmlElement select_Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id = '" + str + "']");

                    XmlElement selectEle1 = (XmlElement)select_Device.SelectSingleNode("/data_chache/Device/parameter[@" + str2 + " = '" + str1 + "']");
                    XmlElement nameEle = (XmlElement)selectEle1.GetElementsByTagName("address")[0];
                    nameEle.InnerText = address_textBox.Text;
                }
                doc.Save(xmlPath);
            }
        }

        private void para_treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (type_comboBox.Text == "主机")
            {
                if (e != null)
                {
                    para_ID_textBox.Text = e.Node.Text.Substring(2);
                }
                XmlDocument doc = new XmlDocument();
                //加载根目录下XML文件
                doc.Load(xmlPath);
                //获取根节点
                XmlElement root = doc.DocumentElement;

                /*设备*/
                XmlElement selectEle = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID='" + para_ID_textBox.Text + "']");
                /*获取起始地址的值*/
                XmlElement host_reg_addr = (XmlElement)selectEle.GetElementsByTagName("host_reg_addr")[0];
                address_textBox.Text = host_reg_addr.InnerText;

                /*获取寄存器类型的值*/
                XmlElement host_reg_mode = (XmlElement)selectEle.GetElementsByTagName("host_reg_mode")[0];
                para_mode_comboBox.Text = host_reg_mode.InnerText;

                /*获取寄存器个数的值*/
                XmlElement host_reg_num = (XmlElement)selectEle.GetElementsByTagName("host_reg_num")[0];
                register_textBox.Text = host_reg_num.InnerText;

                /*获取寄存器个数的值*/
                XmlElement host_reg_value = (XmlElement)selectEle.GetElementsByTagName("host_reg_value")[0];
                register1_text.Text = host_reg_value.InnerText;

                doc.Save(xmlPath);

            }
            else
            {
                uodate_para_para(Convert.ToInt32(e.Node.Text.Substring(2)));
            }
            
        }

        private void equ_treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (type_comboBox.Text == "主机")
            {

            }
            else
            {
                para_treeView.Nodes.Clear();
                uodate_device_para(Convert.ToInt32(e.Node.Text.Substring(2)));
            }
                
        }

        private void register_textBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if ((register_textBox.Text != "1")
                    &&(register_textBox.Text != "2")
                    && (register_textBox.Text != "3")
                    && (register_textBox.Text != "4")
                    )
                {
                    register_textBox.Text = "1"; ;
                    MessageBox.Show("寄存器个数只支持1到4！");
                }
                else
                {
                    XmlDocument doc = new XmlDocument();
                    //加载根目录下XML文件
                    doc.Load(xmlPath);
                    //获取根节点
                    XmlElement root = doc.DocumentElement;

                    string str = ID_textBox.Text;
                    string str1 = para_ID_textBox.Text;
                    String str2 = "D" + ID_textBox.Text + "_P_id";

                    if (type_comboBox.Text == "主机")
                    {
                        XmlElement select = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID = '" + str1 + "']");
                        XmlElement nameEle = (XmlElement)select.GetElementsByTagName("host_reg_num")[0];
                        nameEle.InnerText = register_textBox.Text;
                    }
                    else
                    {
                        XmlElement select_Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id = '" + str + "']");

                        XmlElement selectEle1 = (XmlElement)select_Device.SelectSingleNode("/data_chache/Device/parameter[@" + str2 + " = '" + str1 + "']");
                        XmlElement nameEle = (XmlElement)selectEle1.GetElementsByTagName("reg_num")[0];
                        nameEle.InnerText = register_textBox.Text;
                    }
                    doc.Save(xmlPath);
                }
            }
        }

        private void type_comboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            equ_treeView.Nodes.Clear();
            para_treeView.Nodes.Clear();
            equ_num = 1;
            if (type_comboBox.Text == "主机")
            {
                equ_add_button.Enabled = false;
                equ_dele_button.Enabled = false;
                label4.Visible = true;
                test_radioButton.Visible = true;
                Interval_time_textBox.Visible = true;
                equ_treeView.Nodes.Add("主机");

                XmlDocument doc = new XmlDocument();
                //加载根目录下XML文件
                doc.Load(xmlPath);
                //获取根节点
                XmlElement root = doc.DocumentElement;

                //添加设备IP标记
                XmlElement Device = (XmlElement)root.SelectSingleNode("/data_chache/para[@paranum='1']");

                //获取该标记下的子元素
                XmlElement host_para_num = (XmlElement)Device.GetElementsByTagName("host_para_num")[0];

                int num = Convert.ToInt32(host_para_num.InnerText);

                for (int n = 1; n < num + 1; n++)
                {
                    para_treeView.Nodes.Add("参数" + n.ToString());
                }
            }
            else
            {
                equ_add_button.Enabled = true;
                equ_dele_button.Enabled = true;
                label4.Visible = false;
                Interval_time_textBox.Visible = false;
                test_radioButton.Visible = false;


                XmlDocument doc = new XmlDocument();
                //加载根目录下XML文件
                doc.Load(xmlPath);
                //获取根节点
                XmlElement root1 = doc.DocumentElement;
                //获取<设备>子节点 
                XmlNodeList deviceNodes = root1.GetElementsByTagName("Device");
                //使用foreach循环读出集合
                foreach (XmlNode node in deviceNodes)
                {
                    equ_num++;
                }
                for (int n = 1; n < equ_num; n++)
                {
                    equ_treeView.Nodes.Add("设备" + n.ToString());
                }

                
            }
            
            if (mode_comboBox.Text == "TCP")
            {
                com_set_groupBox.Enabled = false;
            }
            else
            {
                com_set_groupBox.Enabled = true;
            }
        }

        private void scan_com_button_Click(object sender, EventArgs e)
        {
            try
            {
                string[] portlist = SerialPort.GetPortNames();
                for (int i = 0; i < portlist.Length; i++)
                {
                    sele_com_comboBox.Items.Add(portlist[i]);
                }
                sele_com_comboBox.Text = portlist[0];
            }
            catch
            {
                MessageBox.Show("串口没有插上，或者串口驱动有问题", "错误");
            }
        }

        private void open_com_button_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort.PortName = sele_com_comboBox.Text;
                serialPort.BaudRate = Convert.ToInt32(selet_baudrate_comboBox.Text, 10);//十进制数据转换
                serialPort.Open();
                open_com_button.Enabled = false;//打开串口按钮不可用
                colse_com_button.Enabled = true;//关闭串口
            }
            catch
            {
                MessageBox.Show("端口错误,请检查串口", "错误");
            }
            if (type_comboBox.SelectedIndex == 1)
            {
                host_sent_data();
            }
        }

        private void colse_com_button_Click(object sender, EventArgs e)
        {
            serialPort.Close();//关闭串口
            open_com_button.Enabled = true;//打开串口按钮可用
            colse_com_button.Enabled = false;//关闭串口按钮不可用
        }



        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            re_data_num = serialPort.BytesToRead;//
            byte[] buf = new byte[re_data_num];//声明一个临时数组存储当前来的串口数据   
            serialPort.Read(myarray, 0, re_data_num);//读取缓冲数据

            if (re_data_num != 8)
            {
                return;
            }
            if (myarray[1] == 3)
            {
                analysis_data();
            }
            
        }

        private void register1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                XmlDocument doc = new XmlDocument();
                //加载根目录下XML文件
                doc.Load(xmlPath);
                //获取根节点
                XmlElement root = doc.DocumentElement;

                string str = ID_textBox.Text;
                string str1 = para_ID_textBox.Text;
                String str2 = "D" + ID_textBox.Text + "_P_id";
                if (type_comboBox.Text == "主机")
                {
                    XmlElement select = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID = '" + str1 + "']");
                    XmlElement nameEle = (XmlElement)select.GetElementsByTagName("host_reg_value")[0];
                    nameEle.InnerText = register1_text.Text;
                }
                else
                {
                    XmlElement select_Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id = '" + str + "']");

                    XmlElement selectEle1 = (XmlElement)select_Device.SelectSingleNode("/data_chache/Device/parameter[@" + str2 + " = '" + str1 + "']");
                    XmlElement nameEle = (XmlElement)selectEle1.GetElementsByTagName("reg_value")[0];
                    nameEle.InnerText = register1_text.Text;
                }
                doc.Save(xmlPath);
            }
        }

        private void mode_UI_enable(bool isEnable)
        {
            com_set_groupBox.Enabled = isEnable;
        }

        private void mode_comboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (mode_comboBox.Text == "TCP")
            {
                mode_UI_enable(false);
            }
            else
            {
                mode_UI_enable(true);
            }
        }
        void change_host_para_value()
        {
            int num_value;
            XmlDocument doc = new XmlDocument();
            //加载根目录下XML文件
            doc.Load(xmlPath);
            //获取根节点
            XmlElement root = doc.DocumentElement;

            XmlNodeList host_para_Nodes = root.GetElementsByTagName("host_para");
            foreach (XmlNode node in host_para_Nodes)
            {
                XmlNode nameEle = ((XmlElement)node).GetElementsByTagName("host_reg_value")[0];
                num_value = Convert.ToInt32(nameEle.InnerText,10);
                num_value++;
                nameEle.InnerText = num_value.ToString();
            }
            doc.Save(xmlPath);
        }
        private void timer_Tick(object sender, EventArgs e)
        {
            if ((type_comboBox.Text == "主机")&&(open_com_button.Enabled == false))
            {
                timer_tick++;

                int Interval_time = Convert.ToInt32(Interval_time_textBox.Text);

                if ((timer_tick - timer_cache) > (UInt64)(Interval_time))
                {
                    if (test_radioButton.Checked == true)
                    {
                        change_host_para_value();
                        para_treeView_NodeMouseClick(this,null);
                    }
                    host_sent_data();
                }
            }     
        }

        private void para_groupBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.Clear(this.BackColor);
        }

        private void set_groupBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.Clear(this.BackColor);
        }

        private void test_radioButton_Click(object sender, EventArgs e)
        {
            this.test_radioButton.Checked = !this.test_radioButton.Checked;
        }

        private void para_mode_comboBox_TextChanged(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();
            //加载根目录下XML文件
            doc.Load(xmlPath);
            //获取根节点
            XmlElement root = doc.DocumentElement;

            string str = ID_textBox.Text;
            string str1 = para_ID_textBox.Text;
            String str2 = "D" + ID_textBox.Text + "_P_id";
            if (type_comboBox.SelectedIndex == 1)
            {
                XmlElement select_Device = (XmlElement)root.SelectSingleNode("/data_chache/Device[@D_id = '" + str + "']");

                XmlElement selectEle1 = (XmlElement)select_Device.SelectSingleNode("/data_chache/Device/parameter[@" + str2 + " = '" + str1 + "']");
                XmlElement nameEle = (XmlElement)selectEle1.GetElementsByTagName("para_mode")[0];
                nameEle.InnerText = para_mode_comboBox.Text;

                if (para_mode_comboBox.Text == "浮点型")
                {
                    register_textBox.Enabled = false;
                    XmlElement reg_num = (XmlElement)selectEle1.GetElementsByTagName("reg_num")[0];
                    reg_num.InnerText = "2";
                    register_textBox.Text = "2";
                }
                else
                {
                    register_textBox.Enabled = true;
                    XmlElement reg_num = (XmlElement)selectEle1.GetElementsByTagName("reg_num")[0];
                    reg_num.InnerText = "1";
                    register_textBox.Text = "1";
                }

            }
            else
            {
                XmlElement select = (XmlElement)root.SelectSingleNode("/data_chache/host_para[@host_para_ID = '" + str1 + "']");
                XmlElement nameEle = (XmlElement)select.GetElementsByTagName("host_reg_mode")[0];
                nameEle.InnerText = para_mode_comboBox.Text;

                if (para_mode_comboBox.Text == "浮点型")
                {
                    register_textBox.Enabled = false;
                    XmlElement reg_num = (XmlElement)select.GetElementsByTagName("host_reg_num")[0];
                    reg_num.InnerText = "2";
                    register_textBox.Text = "2";
                }
                else
                {
                    register_textBox.Enabled = true;
                    XmlElement reg_num = (XmlElement)select.GetElementsByTagName("host_reg_num")[0];
                    reg_num.InnerText = "1";
                    register_textBox.Text = "1";
                }

            }
            doc.Save(xmlPath);
        }
    }
}
